//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include <c8051f330.h>                 // SFR declarations
#include <stdio.h>
//-----------------------------------------------------------------------------
// 16-bit SFR Definitions for 'F33x
//-----------------------------------------------------------------------------
sfr16 TMR2RL   = 0xca;                 // Timer2 reload value
sfr16 TMR2     = 0xcc;                 // Timer2 counter
//sfr16 ADC0     = 0xbd;                 // ADC Data Word Register
//-----------------------------------------------------------------------------
// Global CONSTANTS
//-----------------------------------------------------------------------------
#define SYSCLK      24500000           // SYSCLK frequency in Hz
#define BAUDRATE        9600           // Baud rate of UART in bps
#define TIMER2_RATE     1000           // Timer 2 overflow rate in Hz

sbit LED = P1^3;                       // LED='1' means ON
//-----------------------------------------------------------------------------
// Function PROTOTYPES
//-----------------------------------------------------------------------------
void PORT_Init (void);
void SYSCLK_Init (void);
void Timer2_Init (int);
void UART0_Init (void);

void fnInitTimer2_2us (void);
void fnDelay2Xus(unsigned int nDelayTime);

#include "DS1820.h"
unsigned char fnGetP1Port(void);

#define CHAN_NUM 2
extern union
{
   	unsigned char c[2];
   	unsigned int x;
}Temperation[CHAN_NUM];


void Delay1s(void)
{
	unsigned int i;
	for(i=1000;i!=0;i--)
	{
		fnDelay2Xus(500);
	}
}


//-----------------------------------------------------------------------------
// Initialization Subroutines
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// PORT_Init
//-----------------------------------------------------------------------------
//
// Configure the Crossbar and GPIO ports.
//
// P0.4 - UART TX
// P0.5 - UART RX
// P1.3 - LED

void PORT_Init (void)
{
   P0SKIP  |= 0x01;                    // Skip P0.0 for external VREF
   P0MDIN  |= 0x01;                    // Configure P0.0 as analog input.
   P0MDOUT |= 0x10;                    // enable UTX as push-pull output

   P1MDOUT |= 0x08;                    // enable LED as push-pull output
   P1MDOUT |= 0x03;						//P1.0,P1.1 as open drain
   P1MDIN  |= 0x03;						//P1.0,P1.1 as Digital Port

   XBR0    = 0x01;                     // Enable UART on P0.4(TX) and P0.5(RX)                     
   XBR1    = 0x40;                     // Enable crossbar and weak pull-ups
}

//-----------------------------------------------------------------------------
// SYSCLK_Init
//-----------------------------------------------------------------------------
//
// This routine initializes the system clock to use the internal oscillator
// at its maximum frequency.
// Also enables the Missing Clock Detector.
//
void SYSCLK_Init (void)
{
   OSCICN |= 0x03;                     // Configure internal oscillator for
                                       // its maximum frequency
   RSTSRC  = 0x04;                     // Enable missing clock detector

}
//-----------------------------------------------------------------------------
// UART0_Init
//-----------------------------------------------------------------------------
//
// Configure the UART0 using Timer1, for <BAUDRATE> and 8-N-1.
//
void UART0_Init (void)
{
   SCON0 = 0x10;                       // SCON0: 8-bit variable bit rate
                                       //        level of STOP bit is ignored
                                       //        RX enabled
                                       //        ninth bits are zeros
                                       //        clear RI0 and TI0 bits
   if (SYSCLK/BAUDRATE/2/256 < 1) {
      TH1 = -(SYSCLK/BAUDRATE/2);
      CKCON &= ~0x0B;                  // T1M = 1; SCA1:0 = xx
      CKCON |=  0x08;
   } else if (SYSCLK/BAUDRATE/2/256 < 4) {
      TH1 = -(SYSCLK/BAUDRATE/2/4);
      CKCON &= ~0x0B;                  // T1M = 0; SCA1:0 = 01                  
      CKCON |=  0x09;
   } else if (SYSCLK/BAUDRATE/2/256 < 12) {
      TH1 = -(SYSCLK/BAUDRATE/2/12);
      CKCON &= ~0x0B;                  // T1M = 0; SCA1:0 = 00
   } else {
      TH1 = -(SYSCLK/BAUDRATE/2/48);
      CKCON &= ~0x0B;                  // T1M = 0; SCA1:0 = 10
      CKCON |=  0x02;
   }

   TL1 = TH1;                          		// init Timer1
   TMOD &= ~0xf0;                      		// TMOD: timer 1 in 8-bit autoreload
   TMOD |=  0x20;                       
   TR1 = 1;                            		// START Timer1
   TI0 = 1;                            		// Indicate TX0 ready
}
//-----------------------------------------------------------------------------
// Timer2_Init SYSCLK no Interrupt
//-----------------------------------------------------------------------------
//
// Configure Timer2 to auto-reload at interval specified by <counts> (no 
// interrupt generated) using SYSCLK as its time base.
//
/*
void Timer2_Init (int counts)
{
   TMR2CN = 0x00;                      		// STOP Timer2; Clear TF2H and TF2L;
                                       		// disable low-byte interrupt; disable
                                       		// split mode; select internal timebase
   CKCON |= 0x10;                      		// Timer2 uses SYSCLK as its timebase

   TMR2RL  = -counts;                  		// Init reload values
   TMR2    = TMR2RL;                   		// Init Timer2 with reload value
//   ET2 = 0;                            	// disable Timer2 interrupts
   ET2 = 1;                            		// lei added
   TR2 = 1;                            		// start Timer2
}
*/
void fnInitTimer2_2us (void)
{
   TMR2CN = 0x00;                      		// STOP Timer2; Clear TF2H and TF2L;
                                       		// disable low-byte interrupt; disable
                                       		// split mode; select internal timebase
   CKCON |= 0x10;                      		// Timer2 uses SYSCLK as its timebase

   TMR2RL  = -49;                  		// Init reload values	lei added 24.5*2=49
   TMR2    = TMR2RL;                   		// Init Timer2 with reload value
   ET2 = 0;                            	// disable Timer2 interrupts
   TR2 = 1;                            		// start Timer2
}

void fnDelay2Xus(unsigned int nDelayTime)
{
   unsigned int count;

   TF2H = 0;                           // Clear Timer2 overflow flag
   TR2 = 1;                            // Start Timer2
   for (count = nDelayTime; count != 0; count--) {
      while (!TF2H);                   // wait for overflow
      TF2H = 0;                        // clear overflow indicator
   }
   TR2 = 0;                            // Stop Timer2
}

//-----------------------------------------------------------------------------
// Interrupt Service Routines
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Timer2_ISR
//-----------------------------------------------------------------------------
// This routine changes the state of the LED whenever Timer2 overflows.
//
/*
void Timer2_ISR (void) interrupt 5
{
	static unsigned int nTimer2Cnt = 0;
	static unsigned int nTimer2Cnt2 = 0;
	
	TF2H = 0;                              	// clear Timer2 interrupt flag
	if(++nTimer2Cnt2==1000)
	{
		nTimer2Cnt2 = 0;
		if(++nTimer2Cnt==1000)
		{  
			nTimer2Cnt = 0; 			
			LED = ~LED;							// change state of LED
		}
	}
}
*/
//-----------------------------------------------------------------------------
// MAIN Routine
//-----------------------------------------------------------------------------
void main (void) 
{
	unsigned int i;
	unsigned char Temp;
   											// Disable Watchdog timer
	PCA0MD &= ~0x40;                    	// WDTE = 0 (clear watchdog timer 
                                       		// enable)
	PORT_Init();                        	// Initialize Port I/O
	SYSCLK_Init ();                     	// Initialize Oscillator
//	Timer2_Init(SYSCLK/TIMER2_RATE);    	// Init Timer 2 
//	Timer2_Init(25);    	// Lei added
	fnInitTimer2_2us();
	UART0_Init();

	LED = 1;
	EA = 1;
	printf ("DS18B20_MultiChan_F330D Ver1.02\n");
/*
	while(1)
	{
//		Temp = fnGetP1Port();
//		printf("P1 Port=0x%02bx\n",Temp);
//		Delay1s();		

		P1 &= 0xfc;
		fnDelay2Xus(32);
		P1 |= 0x03;
		fnDelay2Xus(32);
	}
*/

	Temp = fnOw_Reset();
	if(	Temp == 0 )
	{
		printf("No Port\n");
	}
	else
   	{
		printf("Presence=0x%02bx\n",Temp);		
 	}

//	while(1);

	while(1)
	{
//	  	ow_reset();
		fnOw_Reset();
//  		write_byte(0xCC); // Skip ROM
		fnWriteOneByte(0xcc);
// 		write_byte(0xBE); // Read Scratch Pad
		fnWriteOneByte(0xbe);
//  		T.c[1]=read_byte();
//  		T.c[0]=read_byte();
  		fnReadLowByte();
		fnReadHighByte();

 // 		ow_reset();
		fnOw_Reset();
 // 		write_byte(0xCC); //Skip ROM
		fnWriteOneByte(0xcc);
 // 		write_byte(0x44); // Start Conversion
		fnWriteOneByte(0x44);

//  		printf("Temperation=0x%04x,%02.4f\n",T.x,(float)(T.x)/16);
  		printf("Temp0=0x%04x,%02.4f",Temperation[0].x,(float)(Temperation[0].x)/16);
  		printf("  Temp1=0x%04x,%02.4f\n",Temperation[1].x,(float)(Temperation[1].x)/16);

		Delay1s();
	}


	while(1)
	{
		for(i=1000;i!=0;i--)
		{
			fnDelay2Xus(500);
		}
		LED ^=1;
	}
	while(1);	
}
